package com.aica.util;

import com.aica.constant.StringBuilderConstant;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义jwt生成token工具类
 * @author yly
 */
@Slf4j
public class JwtTokenUtil {


    /**
     * 自定义密钥
     */
    private static final String SECRET = "c0fb33df6b54d6f8b4df8h9bdfh4ty8eh1i86jygiy9F87SG96B4DF87HD9B84T";



    /**
     * 生成token
     * @param username 用户name
     * @param roleIds 角色id集合
     * @return token字符串（不携带标头Bearer ）
     */
    public static String getToken(String username,List<Integer> roleIds) {
        String token="";
        Map<String, Object> map = new HashMap<>(2);
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        token= JWT.create()
                .withHeader(map)
                .withClaim("username",username)
                .withClaim("roleIds",roleIds)
                //新增时间戳，作为随机值，避免每次生成的token都不变
                .withClaim("currentTime",System.currentTimeMillis())
                //设置过时时间
                //.withExpiresAt(null==date ? new Date(System.currentTimeMillis() + 1000*60*60*24*15) : date )
                .sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    /**
     * 校验token是否合法
     * @param token token字符串（不携带标头Bearer ）
     * @return token中携带的有效信息集合
     */
    public static Map<String, Claim> verifyToken(String token) {
        String s = token.replace(StringBuilderConstant.TARGET, "");
        DecodedJWT jwt;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt = verifier.verify(s);
        } catch (Exception e) {
            //e.printStackTrace();
            //throw new JWTVerificationException("token校验失败");
            log.error("token校验失败,该token可能非法或为空");
            return null;
        }

        return jwt.getClaims();
    }

    /**
     * 获取token中的用户name
     * @param token token字符串（不携带标头Bearer ）
     * @return token中的username
     */
    public static String getUserNameForToken(String token){
        Map<String, Claim> claims = verifyToken(token);
        if(claims==null){
            return null;
        }
        Claim userNameClaim = claims.get("username");
        if (null == userNameClaim ) {
            log.error("token 校验失败,无法获得username字段");
            throw new JWTVerificationException("token校验失败");
        }
        return userNameClaim.asString();
    }

    /**
     * 获取token中的角色id集合
     * @param token token字符串（不携带标头Bearer ）
     * @return token中的roleIds
     */
    public static List<Integer> getRoleIdsForToken(String token){
        Map<String, Claim> claims = verifyToken(token);
        if(claims==null){
            return null;
        }
        Claim levelIdClaim = claims.get("roleIds");
        if (null == levelIdClaim || levelIdClaim.asList(Integer.class).isEmpty()) {
            log.error("token 校验失败,无法获得roleIds字段");
            throw new JWTVerificationException("token校验失败");

        }
        return levelIdClaim.asList(Integer.class);
    }
}
